/**
 * 饼状图、环状图
 * circleChartsC (reactCharts)
 * @author zxy
 * @date  2020-05-26
 */
import React from 'react';
import ReactEcharts from 'echarts-for-react';
import PropTypes from 'prop-types';
import { Spin } from 'antd';
import { NoDataC } from '@/src/components';
import color from '../../../css/colors';

class circleChartsC extends React.Component {
  // 入参默认值设置
  static defaultProps = {
    data: undefined,
    type: 'pie', // 默认饼状图
    height: '100%', // 图形高度默认为父节点的100%
    width: '100%', // 图形宽度默认为父节点的100%
    colors: color.echart, // 默认系统色
    toolTipFormat: undefined, // 默认按自定义的提示信息样式展示
    showLegend: true, // 默认展示图例
    showLable: false, // 默认不展示图形上的文本标签
    unit: '', // 数值单位
    text: '', // 一级标题
    subText: '', // 二级标题
    legendX: '70%', // 图例距离左侧的距离
    textTop: '40%', // 标题距离上方的距离
    radius: undefined, // 默认不设置环占比
    lableFormatter: 'type1', // 默认文本展示样式
    lablePadding: undefined, // 文字块的内边距
    labelLine: {}, // 视觉引导线的长度
    position: undefined, // 图形位置
    center: ['center', 'center'], // 设置饼状图位置，第一个百分数调水平位置，第二个百分数调垂直位置
    legendPosition: undefined, // 图例位置
    showBorder: false, // 默认展示边框
    legend: undefined, // 默认由系统自动从series中分析
    startAngle: 90, // 默认90度
    legendFormat: '1', // 图例显示格式   '0':name,'1':name-value/100,'2':name-value/100-(value)  '3':value
    onEvents: () => {}, // 默认点击事件
    legendTextWidth: 130, // 图例文本显示宽度，默认130
    titleLeft: 'center', // 一级标题的左侧距离
    titleSize: 24, // 一级标题的左侧大小
  };

  // 返回option
  getOption = (legend, series) => {
    const {
      colors,
      toolTipFormat,
      legendFormat,
      showLegend,
      unit,
      text,
      subText,
      legendX,
      textTop,
      legendPosition,
      legendFormatter,
      legendTextWidth,
      colorType,
      titleLeft,
      titleSize,
    } = this.props;
    let colorss;
    switch (colorType) {
      case 'darkBlue':
        colorss = color.darkBlueEchart;
        break;
      case 'red':
        colorss = color.redEchart;
        break;
      default:
        colorss = colors;
    }
    const dataSource = this.changeData(series);
    return {
      // 调色盘颜色列表
      color: colorss,
      backgroundColor: colorType == 'red' ? color.echartItems.bgColorR : colorType == 'darkBlue' ? color.echartItems.bgColorD : color.echartItems.bgColor, // echarts整个画布的背景色
      // 主标题和副标题
      title: {
        text,
        subtext: subText,
        top: textTop,
        left: titleLeft,
        textStyle: {
          fontSize: titleSize,
          color: color.echartItems.title,
        },
        subtextStyle: {
          color: color.echartItems.legend,
          fontSize: 14,
        },
      },
      // 鼠标移动上去提示信息
      tooltip: {
        // trigger 设置触发类型，默认数据触发，可选值：'item' ¦ 'axis'
        trigger: 'item',
        showDelay: 20, // 显示延迟，添加显示延迟可以避免频繁切换，单位ms
        hideDelay: 20, // 隐藏延迟，单位ms
        // formatter设置提示框显示内容
        // {a}指series.name  {b}指series.data的name
        // {c}指series.data的value  {d}%指这一部分占总数的百分比
        // formatter: '{a} <br/>{b} : {c}个 ({d}%)',

        formatter: toolTipFormat
          ? toolTipFormat
          : (params) => {
              return `<div style="display:flex;align-items:center;margin-bottom:8px;color:${color.echartItems.tooltipLabel}">
                      <div style="border:1px solid ${color.echartItems.toolLable};width:10px;height:10px;border-radius:50%;background-color:${params.color};margin-right:8px"></div>
                      ${params.name}： ${params.data.valueOriginal}${unit}（占比：${params.percent}%）
                   </div>`;
            },
        padding: [12, 12, 4, 12],
        confine: true,
        backgroundColor: color.echartItems.tooltipBgColor,
        extraCssText: `box-shadow: 0px 2px 12px 0px ${color.echartItems.tooltipBgShadow};border-radius: 4px;opacity: 0.65;font-size: 12px;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;`,
      },
      // 图例
      legend: {
        show: showLegend,
        // orient 设置布局方式，默认水平布局，可选值：'horizontal'（水平） ¦ 'vertical'（垂直）
        orient: 'vertical',
        // x 设置水平安放位置，默认全图居中，可选值：'center' ¦ 'left' ¦ 'right' ¦ {number}（x坐标，单位px）
        x: legendX,
        // y 设置垂直安放位置，默认全图顶端，可选值：'top' ¦ 'bottom' ¦ 'center' ¦ {number}（y坐标，单位px）
        y: 'center',
        ...legendPosition,
        itemWidth: 8, // 设置图例图形的宽
        itemHeight: 8, // 设置图例图形的高
        // itemGap设置各个item之间的间隔，单位px，默认为10，横向布局时为水平间隔，纵向布局时为纵向间隔
        itemGap: 12,
        data: legend,
        formatter: legendFormatter
          ? legendFormatter
          : (name) => {
              // 图例上显示的饼图各模块上的名字
              // 获取legend显示内容
              const { data } = series[0];
              let total = 0;
              let tarValue = 0;
              for (let i = 0, l = data.length; i < l; i++) {
                total += Number(data[i].value);
                if (data[i].name == name) {
                  tarValue = Number(data[i].value);
                }
              }
              const percent = ((tarValue / total) * 100).toFixed(2);
              return legendFormat == '0'
                ? name
                : legendFormat == '1'
                ? `{a|${name}}{b|${percent}%}`
                : legendFormat == '3'
                ? `{a|${name}}{b|${tarValue}}`
                : `{a|${name}}{b|${percent}%（${tarValue}）}`;
            },
        textStyle: {
          color: color.echartItems.legend,
          fontSize: 12,
          width: legendTextWidth,
          rich: {
            a: {
              align: 'left',
            },
            b: {
              align: 'right',
            },
          },
        },
      },
      // 数据
      series: dataSource,
    };
  };

  // 处理数据为负值情况---饼状图展示正值
  changeData = (data) => {
    const arr = JSON.parse(JSON.stringify(data));
    arr.map((item) => {
      const dataSource = item.data;
      if (dataSource && dataSource.length > 0) {
        dataSource.map((item) => {
          item.valueOriginal = item.value;
          item.value = Math.abs(item.value);
        });
      }
    });
    return arr;
  };

  clickEvents = (r) => {
    this.props.onEvents(r);
  };

  render() {
    const { data, height, width, showBorder, radius, showLable, lableFormatter, type, legend, startAngle, lablePadding, labelLine, position, center } = this.props;

    const initStatus = data !== undefined && data !== null;
    const legendS = [];
    let series = [];
    if (initStatus) {
      // 公共参数
      const seriesCommon = {
        type: 'pie',
        center, // 设置饼状图位置，第一个百分数调水平位置，第二个百分数调垂直位置
        ...position, // 图形位置
        hoverOffset: 2, // 高亮扇区的偏移距离
        selectedOffset: 2, // 选中扇区的偏移距离
        startAngle,
        label: {
          show: showLable,
          formatter: lableFormatter === 'type1' ? '{b}：{d}%' : lableFormatter === 'type2' ? '{b}({d}%)\n{c}' : lableFormatter === 'type3' ? '{d}%' : lableFormatter,
          fontSize: 14,
          alignTo: 'labelLine',
          bleedMargin: 5,
          padding: lablePadding,
          // fontSize:12
        },
        labelLine: {
          ...labelLine,
        },
      };
      // 多环
      if (data[0] instanceof Array) {
        data.forEach((item, index) => {
          series.push({
            radius: [`${55 - index * 15}%`, `${65 - index * 15}%`], // 计算每个环的radius
            data: item,
            ...seriesCommon,
          });
          // 当从外部设置了图例，则用外部设置的图例，若没设置，则自行从series中分析
          if (!legend) {
            item.forEach((ele) => {
              legendS.push({
                name: ele.name,
                icon: 'rect',
              });
            });
          } else {
            legend.forEach((ele) => {
              legendS.push({
                name: ele,
                icon: 'rect',
              });
            });
          }
        });
      } else {
        // 单环
        // 当从外部设置了图例，则用外部设置的图例，若没设置，则自行从series中分析
        if (!legend) {
          data.forEach((item) => {
            legendS.push({
              name: item.name,
              icon: 'rect',
            });
          });
        } else {
          legend.forEach((ele) => {
            legendS.push({
              name: ele,
              icon: 'rect',
            });
          });
        }
        series = [
          {
            radius: radius ? radius : type === 'pie' ? '65%' : ['40%', '65%'], // 设置环形饼状图， 第一个百分数设置内圈大小，第二个百分数设置外圈大小
            data,
            ...seriesCommon,
          },
        ];
      }
    }

    return (
      <div style={{ border: showBorder && `1px solid ${color.echartItems.border}` }}>
        <Spin spinning={!initStatus} tip='加载中...'>
          {initStatus ? (
            data.length > 0 ? (
              <ReactEcharts
                option={this.getOption(legendS, series)}
                style={{ height, width }}
                // 是否不跟之前设置的 option 进行合并，默认为 false，即合并。
                notMerge={true}
                onEvents={{ click: this.clickEvents }}
              />
            ) : (
              <NoDataC />
            )
          ) : (
            <div style={{ height, width }}></div>
          )}
        </Spin>
      </div>
    );
  }
}

/*
备注：
  当series值为null或undefined时，显示loading状态
  当series值为空数组[]时，显示“暂无数据”
  当series值为有值的数组时，正常实现图形
*/

circleChartsC.propsTypes = {
  data: PropTypes.array, // [{value:数值,name:名称}]
  type: PropTypes.oneOf([
    // 图表类型
    'pie', // 饼状图
    'ring', // 环形图
  ]),
  height: PropTypes.oneOfType([
    // 图表高度（百分比或数值）
    PropTypes.string,
    PropTypes.number,
  ]),
  width: PropTypes.oneOfType([
    // 图表宽度（百分比或数值）
    PropTypes.string,
    PropTypes.number,
  ]),
  colors: PropTypes.array, // 图表颜色
  toolTipFormat: PropTypes.func, // 提示框内容显示格式处理
  showLable: PropTypes.bool, // 是否显示图形上的文本标签
  showLegend: PropTypes.bool, // 是否显示图例
  lableFormatter: PropTypes.oneOfType([
    // 文本标签的格式（showLable为true时有效）
    PropTypes.string,
    PropTypes.func,
  ]),
  lablePadding: PropTypes.array, // 文字块的内边距
  labelLine: PropTypes.object, // 视觉引导线的长度
  center: PropTypes.array, // 设置饼状图位置，第一个百分数调水平位置，第二个百分数调垂直位置
  position: PropTypes.object, // 图形位置
  legendPosition: PropTypes.object, // 图例位置
  unit: PropTypes.string, // 数值单位
  text: PropTypes.string, // 一级标题
  subText: PropTypes.string, // 二级标题
  textTop: PropTypes.string, // 标题距离上方的距离
  legendX: PropTypes.string, // 图例距离左侧的距离
  radius: PropTypes.oneOfType([
    // 图表环所占百分比（当是环形图时，传数组，当是饼状图时，传数值）
    PropTypes.string,
    PropTypes.array,
  ]),
  showBorder: PropTypes.bool, // 标记是否展示边框
  legend: PropTypes.array, // 图例（若不传该参数，组件从series中自行分析）
  startAngle: PropTypes.number, // 绘图起始角度
  legendFormat: PropTypes.string, // 图例显示格式   '0':语文,'1':语文   30%,'2':语文   30%（100）
  onEvents: PropTypes.func, // 点击事件
  legendFormatter: PropTypes.func, // 图例自定义样式
  legendTextWidth: PropTypes.number, // 图例文本显示宽度
  titleLeft: PropTypes.number, // 一级标题的左侧距离
  titleSize: PropTypes.number, // 一级标题的左侧大小
};
export default circleChartsC;
